﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using System.Net;
using System.Collections;
using System.Xml;
using System.Reflection;
using System.Web;
using System.Diagnostics;
using System.Threading;

namespace SlideShow
{
    public partial class SuperSign : Form
    {

        //private string m_assetID;//ID in the database tt
        //private string m_assetID = "5937";
        //private string m_assetID;//ID in the database tt
        private string m_assetID = "5958";
        private string  m_consumerKey = "56mrkw3ejdx2ucz";
        private string m_consumerSecret = "b8lm9tiecf1goav";
        private string m_xml = "images.xml";
        private int m_selected = 0;
        private int m_begin = 0;
        private int m_end = 0;
        //private string m_lastest_schedules;
        private int m_playList_num;
        private Schedule_item m_playlist = new Schedule_item();
        private ArrayList m_images_cache = new ArrayList();// store images will be displayed
        private ArrayList m_images_array = new ArrayList();

        private Schedule m_schedule_manager;
        private DropboxApi m_dropboxAPI;
        private ArrayList m_log_array = new ArrayList();//temporary record log info during playing back
        

        public SuperSign()
        {
            InitializeComponent();
            //display a default image
            //if(!IS_crashed)
            m_dropboxAPI = new DropboxApi(m_consumerKey, m_consumerSecret);
            m_dropboxAPI.initial();
            m_schedule_manager = new Schedule(m_assetID);
            m_schedule_manager.get_schedule_DB();
            DD_Interval_select.DropDownStyle = ComboBoxStyle.DropDownList;
            m_playList_num = (int)(30 / Convert.ToInt32(DD_Interval_select.Text));
            Console.WriteLine("m_playlist_size = "+m_playList_num);
            Access_DB_timer.Enabled = true;
            Check_schedule_timer.Enabled = true;
            //else



            ////get initial picture from resource
            ////Assembly assem = this.GetType().Assembly;
            ////pic_display.Image = (System.Drawing.Image)Properties.Resources._default;
            ////m_assetID = (String)Properties.Settings.Default.AssetID;
            //button_start.Enabled = true;

            ////Properties.Settings.

            //Pic_dis_timer.Enabled = false;
            ////Access_DB_Timer.Enabled = true;
            //Check_schedule_timer.Enabled = true;//edit
            //Check_download_timer.Enabled = true;
            //DD_Interval_select.DropDownStyle = ComboBoxStyle.DropDownList;

        }

        private void Pic_dis_timer_Tick(object sender, EventArgs e)
        {
            nextImage();
        }

        private void Access_DB_timer_Tick(object sender, EventArgs e)
        {

            if (((DateTime.Now.Minute >= 27) && (DateTime.Now.Minute <= 28))
                || (DateTime.Now.Minute >= 57) && (DateTime.Now.Minute <= 58))//need modify
            {
                Access_DB_timer.Enabled = false;
                //m_schedule_manager.get_schedule_DB();
                Thread t_SQL = new Thread(new ThreadStart(m_schedule_manager.get_schedule_DB));
                t_SQL.Start();//It's the best solution: set Access_DB_timer.Enabled = true after the thread finish
                //if (!t_SQL.IsAlive)
                //{
                //    Access_DB_timer.Enabled = true;
                //}
                Console.WriteLine("Check_schedule_timer.Enabled=" + Check_schedule_timer.Enabled);
            }
        }

        private void Check_schedule_timer_Tick(object sender, EventArgs e)
        {
            if (m_schedule_manager.DB_schedule.Count != 0)//edit
            {
                //compare to schedule
                DateTime pre_date = ((DateTime)m_schedule_manager.DB_schedule[0]); //schedule
                DateTime post_date = ((DateTime)m_schedule_manager.DB_schedule[0]).AddMilliseconds(500);
                int compare_pre_date = DateTime.Now.CompareTo(pre_date);//compare to time now
                int compare_post_date = DateTime.Now.CompareTo(post_date);//compare to time now
                if (compare_pre_date >= 0 && compare_post_date <= 0)//make sure the DateTime is almost the right time
                {
                    Check_schedule_timer.Enabled = false;//timer for check when to display 
                    //Access_DB_timer.Enabled = true;
                    m_selected = 0;
                    //DD_Interval_select.SelectedIndex = (int)(Pic_dis_timer.Interval / 1000) - 1;
                    ////get playlist
                    //m_playList_num = (int)(30 / Convert.ToInt32(DD_Interval_select.Text));
                    Console.WriteLine("m_playlist_size = " + m_playList_num);
                    ArrayList tmp_images = m_dropboxAPI.get_playlist(m_playList_num);
                    m_playlist = m_schedule_manager.create_schedule(tmp_images);
                    m_playList_num = m_playlist.images.Count;
                    Pic_dis_timer.Interval = ((int)30 / m_playList_num) * 1000;
                    Console.WriteLine("play back interval = "+Pic_dis_timer.Interval);
                    pic_display.Image = ((Image_item)(m_playlist.images)[m_selected]).image;//display pic
                    RT_status.Text += ((Image_item)m_playlist.images[m_selected]).file_name + "\n";
                    //record log
                    m_log_array.Add(new Log_item(((Image_item)m_playlist.images[m_selected]).file_name, DateTime.Now.ToString()));
                    m_schedule_manager.DB_schedule.RemoveAt(0);
                    Pic_dis_timer.Enabled = true;
                }
            }
        }

      
        //modify image to 16:9 and 1280*720
        private Image modify_image(Image image)
        {
            return image;
        }
        

       

        private void button_start_Click(object sender, EventArgs e)
        {
            //Pic_dis_timer.Interval = Convert.ToInt32(DD_Interval_select.Text) * 1000;
            m_playList_num = (int)(30 / Convert.ToInt32(DD_Interval_select.Text));
            RT_status.Text = RT_status.Text + "Display interval time is " + DD_Interval_select.Text + " second(s) \n";
            RT_status.Text = RT_status.Text + "Next playlist have  " + m_playList_num + " pictures \n";
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            Pic_dis_timer.Enabled = false;
        }

        private Image ImageCropResize(Image image, int width, int height)
        {
            Bitmap bmpImage = new Bitmap(image);
            Image final_image = image;
            //crop
            //specify the crop area
            Rectangle cropArea = new Rectangle();
            cropArea.Width = image.Width;
            cropArea.Height = (int)(cropArea.Width * 9 / 16);
            int location_y = (int)(image.Height / 2 - cropArea.Height / 2);
            cropArea.Location = new Point(0, location_y);
            if (location_y < 0)
            {
                cropArea.Height = image.Height;
                cropArea.Width = (int)(cropArea.Height * 16 / 9);
                cropArea.Location = new Point((int)(image.Width / 2 - cropArea.Width / 2), 0);
            }
            //crop the image  get the bmpCrop
            Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
            //resize
            final_image = resizeImage((Image)bmpCrop, new Size(width, height));
            return final_image;
        }
        private Image resizeImage(Image imgToResize, Size size)
        {
            int sourceWidth = imgToResize.Width;
            int sourceHeight = imgToResize.Height;
            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;
            nPercentW = ((float)size.Width / (float)sourceWidth);
            nPercentH = ((float)size.Height / (float)sourceHeight);

            if (nPercentH < nPercentW)
                nPercent = nPercentH;
            else
                nPercent = nPercentW;

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmpImage = new Bitmap(destWidth, destHeight);
            Graphics graphics = Graphics.FromImage((Image)bmpImage);
            graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            graphics.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
            graphics.Dispose();

            return (Image)bmpImage;
        }




       
        private void nextImage()
        {
            if (m_selected == m_playlist.images.Count - 1)
            {
                m_selected = 0;
                Pic_dis_timer.Enabled = false;
                Check_schedule_timer.Enabled = true;
                //write log  whole playlist
                write_log_array(m_log_array);
                m_log_array.Clear();
            }
            else
            {
                //Write_log("1.jpg", "8/9/2013");
                m_selected = m_selected + 1;
                pic_display.Image = ((Image_item)m_playlist.images[m_selected]).image;
                RT_status.Text += ((Image_item)m_playlist.images[m_selected]).file_name + "\n";
                m_log_array.Add(new Log_item(((Image_item)m_playlist.images[m_selected]).file_name, DateTime.Now.ToString()));
            }
        }

        private void Start_dis_timer_Tick_1(object sender, EventArgs e)
        {
            
            //m_schedule_manager.schedules.RemoveAt(0);
            Pic_dis_timer.Enabled = true;
            Start_dis_timer.Enabled = false;
        }


        private void write_log_array(ArrayList log_array)
        {
            XmlDocument xmldoc = new XmlDocument();
            XmlElement root = null;
            try
            {
                xmldoc.Load(m_xml);
                root = xmldoc.DocumentElement;
                if (root != null)
                {
                    XmlElement theImage = null, theElem = null;

                    foreach(Log_item log in log_array)
                    {
                        //create a new element
                        theImage = xmldoc.CreateElement("Image");
                        theElem = xmldoc.CreateElement("file_name");
                        theElem.InnerText = log.file_name;
                        theImage.AppendChild(theElem);

                        theElem = xmldoc.CreateElement("display_time");
                        theElem.InnerText = log.date;
                        theImage.AppendChild(theElem);

                        root.AppendChild(theImage);
                    }
                }
                xmldoc.Save(m_xml);
            }
            catch (Exception exception)
            {
                Console.Out.WriteLine(exception.Message);
            }
        }

        //return true if write the log successfully
        private bool write_log(string file_name, string date)
        {
            XmlDocument xmldoc = new XmlDocument();
            XmlElement root = null;
            try
            {
                xmldoc.Load(m_xml);
                root = xmldoc.DocumentElement;
                if (root != null)
                {
                    XmlElement theImage = null, theElem = null;

                    //create a new element
                    theImage = xmldoc.CreateElement("Image");
                    theElem = xmldoc.CreateElement("file_name");
                    theElem.InnerText = file_name;
                    theImage.AppendChild(theElem);

                    theElem = xmldoc.CreateElement("display_time");
                    theElem.InnerText = date;
                    theImage.AppendChild(theElem);

                    root.AppendChild(theImage);
                }
                xmldoc.Save(m_xml);
                return true;
            }
            catch (Exception exception)
            {
                Console.Out.WriteLine(exception.Message);
                return false;
            }
        }

        private string read_log()
        {
            XmlDocument xmldoc = new XmlDocument();
            XmlElement root = null;
            try
            {
                xmldoc.Load(m_xml);
                root = xmldoc.DocumentElement;
                XmlElement lastImage = (XmlElement)root.SelectSingleNode("/Images/Image[position()=last()]");
                string fileName = lastImage.FirstChild.InnerText.ToString();
                return fileName;
            }
            catch (Exception exception)
            {
                Console.Out.WriteLine(exception.Message);
                return null;
            }
        }

        
        private void test_dropbox_Click(object sender, EventArgs e)
        {
            //DropboxApi dropbox = new DropboxApi(m_consumerKey,m_consumerSecret);
            //dropbox.initial();

            //Thread t_maintain = new Thread(new ThreadStart(dropbox.maintain()));
            //t_maintain.Start();
            //tmp.dropbox_author();
            //var account = tmp.GetAccountInfo();
            //Console.WriteLine(account);
            //var publicFolder = tmp.GetFiles("dropbox", "Live");
            ////var publicFolder = tmp.GetFiles("dropbox", "/Live");
            //foreach (var file in publicFolder.Contents)
            //{
            //    Console.WriteLine(file.Path);
            //    Console.WriteLine(file.Modified);
            //    var files = tmp.DownloadFile("dropbox", file.Path);
            //    Image image_tmp = files.return_image();
            //    pic_display.Image = ImageCropResize(image_tmp,640,360);
            //    break;
            //}
            
        }

    }

    public class Log_item
    {
        public string file_name;
        public string date;
        public Log_item(string file_name, string date)
        {
            this.file_name = file_name;
            this.date = date;
        }
        public Log_item() { }
    }
}
